package  modelo.gestionReserva;
import interfacesRemotas.InterfazReserva;

import java.io.Serializable;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.text.DateFormat;
import java.util.*;

import aplicaciones.Main;
import modelo.*;

/**
 * @version 1.0
 * @created 21-mar-2007 21:39:25
 */
public class Reserva implements Serializable  {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private int comensales;
	private Date fecha;
	private Date hora;
	private String nombreCliente;
	private int idMesaTitular;
	private Mesa[] m_Mesas;
	private String ip;
	private int id_reserva;

	
	
	public Reserva(int id, int c, Date h, Date f, String nombre, String ip){
		this.comensales = c;
		this.hora = h;
		this.fecha = f;
		this.nombreCliente = nombre;
		m_Mesas = null;
		this.ip = ip;
		this.id_reserva = id;
	}

	public void finalize() throws Throwable {

	}

	public void anularReserva(){
		try {
			InterfazReserva ar = (InterfazReserva)Naming.lookup("//" + this.ip + "/AccesoReserva");
			ar.deleteReserva(id_reserva);
			
			System.out.println("Borrando la reserva de id " + id_reserva);
			
		} catch (MalformedURLException e) {
			System.err.println("Error en la clase Reserva en el metodo anularReserva: " + e.getMessage());
		} catch (RemoteException e) {
			System.err.println("Error en la clase Reserva en el metodo anularReserva: " + e.getMessage());
		} catch (NotBoundException e) {
			System.err.println("Error en la clase Reserva en el metodo anularReserva: " + e.getMessage());
		}
	}

	/**
	 *
	 * @param m
	 */
	public void setMesa(Mesa m, boolean actualizar){
		
		if (m_Mesas != null){
			Mesa aux[] = new Mesa[m_Mesas.length+1];
		
			System.arraycopy(m_Mesas, 0, aux, 0, m_Mesas.length);
		
			m_Mesas = aux;
		
			aux[m_Mesas.length - 1] = m;
		}
		else {
			m_Mesas = new Mesa[1];
			m_Mesas[0] = m;
		}
		
		if (actualizar){
			
			try {
				InterfazReserva ar = (InterfazReserva)Naming.lookup("//" + this.ip + "/AccesoReserva");
				ar.insertMesa(id_reserva, m.getNumMesa());
			} catch (MalformedURLException e) {
				System.err.println("Error en la clase Reserva en el metodo setMesaTitular: " + e.getMessage());
			} catch (RemoteException e) {
				System.err.println("Error en la clase Reserva en el metodo setMesaTitular: " + e.getMessage());
			} catch (NotBoundException e) {
				System.err.println("Error en la clase Reserva en el metodo setMesaTitular: " + e.getMessage());
			}
		}
	}

	public int getComensales(){
		return this.comensales;
	}

	public String getFecha(){
		DateFormat df = DateFormat.getDateInstance();
		return df.format(fecha);
	}

	
	public Date obtenerFecha(){
		return fecha;
	}
	
	public Date obtenerHora(){
		return hora;
	}
	
	public String getHora(){
		DateFormat df = DateFormat.getTimeInstance();
		return df.format(fecha);
	}

	public String getNombreCliente(){
		return this.nombreCliente;
	}

	/**
	 *
	 * @param nuevos_comensales
	 */
	public void setComensales(int nuevos_comensales){
		this.comensales = nuevos_comensales;
		
		try {
			InterfazReserva ar = (InterfazReserva)Naming.lookup("//" + this.ip + "/AccesoReserva");

			ar.updateReserva(nuevos_comensales, fecha, hora, nombreCliente, nombreCliente, fecha, hora);
		} catch (MalformedURLException e) {
			System.err.println("Error en la clase Reserva en el metodo setComensales: " + e.getMessage());
		} catch (RemoteException e) {
			System.err.println("Error en la clase Reserva en el metodo setComensales: " + e.getMessage());
		} catch (NotBoundException e) {
			System.err.println("Error en la clase Reserva en el metodo setComensales: " + e.getMessage());
		}
	}

	/**
	 *
	 * @param nueva_fecha
	 */
	public void setFecha(Date nueva_fecha){
		this.fecha = nueva_fecha;
		try {
			InterfazReserva ar = (InterfazReserva)Naming.lookup("//" + this.ip + "/AccesoReserva");
			
			ar.updateReserva(comensales, fecha, hora, nombreCliente, nombreCliente, nueva_fecha, hora);
		} catch (MalformedURLException e) {
			System.err.println("Error en la clase Reserva en el metodo setFecha: " + e.getMessage());
		} catch (RemoteException e) {
			System.err.println("Error en la clase Reserva en el metodo setFecha: " + e.getMessage());
		} catch (NotBoundException e) {
			System.err.println("Error en la clase Reserva en el metodo setFecha: " + e.getMessage());
		}
	}

	/**
	 *
	 * @param nueva_hora
	 */
	public void setHora(Date nueva_hora){
		this.hora = nueva_hora;
		
		try {
			InterfazReserva ar = (InterfazReserva)Naming.lookup("//" + this.ip + "/AccesoReserva");
			
			ar.updateReserva(comensales, fecha, hora, nombreCliente, nombreCliente, nueva_hora, hora);
		} catch (MalformedURLException e) {
			System.err.println("Error en la clase Reserva en el metodo setHora: " + e.getMessage());
		} catch (RemoteException e) {
			System.err.println("Error en la clase Reserva en el metodo setHora: " + e.getMessage());
		} catch (NotBoundException e) {
			System.err.println("Error en la clase Reserva en el metodo setHora: " + e.getMessage());
		}
	}

	/**
	 *
	 * @param nuevo_nombre
	 */
	public void setNombreCliente(String nuevo_nombre){
		this.nombreCliente = nuevo_nombre;
		try {
			InterfazReserva ar = (InterfazReserva)Naming.lookup("//" + this.ip + "/AccesoReserva");
			ar.updateReserva(comensales, fecha, hora, nuevo_nombre, nombreCliente, hora, hora);
		} catch (MalformedURLException e) {
			System.err.println("Error en la clase Reserva en el metodo setNombreCliente: " + e.getMessage());
		} catch (RemoteException e) {
			System.err.println("Error en la clase Reserva en el metodo setNombreCliente: " + e.getMessage());
		} catch (NotBoundException e) {
			System.err.println("Error en la clase Reserva en el metodo setNombreCliente: " + e.getMessage());
		}
	}

	public Mesa[] getMesas(){
		return m_Mesas;
	}

	/**
	 *
	 * @param m
	 */
	public void setMesaTitular(Mesa m, boolean actualizar){
		idMesaTitular=m.getNumMesa();
		setMesa(m, actualizar);
		
		if (actualizar){
			try {
				InterfazReserva ar = (InterfazReserva)Naming.lookup("//" + this.ip + "/AccesoReserva");
				ar.insertMesaTitular(id_reserva, m.getNumMesa());
			} catch (MalformedURLException e) {
				System.err.println("Error en la clase Reserva en el metodo setMesaTitular: " + e.getMessage());
			} catch (RemoteException e) {
				System.err.println("Error en la clase Reserva en el metodo setMesaTitular: " + e.getMessage());
			} catch (NotBoundException e) {
				System.err.println("Error en la clase Reserva en el metodo setMesaTitular: " + e.getMessage());
			}
		}
	}

	public int getIdMesaTitular() {
		return idMesaTitular;

	}
	public boolean equals(Object o){
		if (o instanceof Reserva) {
			Reserva p = (Reserva) o;
			if (this.nombreCliente.equals(p.getNombreCliente())
				&&
				this.fecha.equals(p.getFecha())
				&&
				this.hora.equals(p.getHora())
			)
				return true;
		}
		return false;
	}
	/**
	 *
	 * @param res
	 * @param r
	 */
	public static void seleccionarMesas(Restaurante res, Reserva r)
	{
		int restantes = r.comensales;
		int libres = -1;
		int min_libres = 99999;
		int pos_min =  -1;
		
		r.eliminarMesas();
		
		//TODO hay que comprobar el estado de las mesas a la hora de la reserva
		
		// buscamos entre todas las mesas hasta encontrar una mesa que nos valga
		for (int i=0; i<res.getMesas().size(); i++){
			if (res.getMesas().get(i).getCapacidadMax() >= r.comensales && res.mesaLibre(r.fecha, r.hora, res.getMesas().get(i))){
				libres = res.getMesas().get(i).getCapacidadMax() - r.comensales;
				
				if (libres < min_libres){
					min_libres = libres;
					pos_min = i;
				}
			}
		}
		
		if (libres != -1) {
			System.out.println("Hemos encontrado una mesa para todos");
			r.setMesaTitular(res.getMesas().get(pos_min), true);
		}	
		
		// si no encontramos una sóla mesa para la reserva, buscamos una o más mesas
		if (libres == -1){
			
			boolean titular = false;
			
			for (int i=0; i<res.getMesas().size() && restantes > 0; i++){
				if (res.mesaLibre(r.fecha, r.hora, res.getMesas().get(i))){
					if (!titular){
						titular = true;
						r.setMesaTitular(res.getMesas().get(i), true);
					}
					else
						r.setMesa(res.getMesas().get(i), true);
					restantes -= res.getMesas().get(i).getCapacidadMax();
					
						
				}
			}
		}
	}


	public int getId_reserva() {
		return id_reserva;
	}


	public void setId_reserva(int id_reserva) {
		this.id_reserva = id_reserva;
	}
	
	public void eliminarMesas(){
		
		try {
			InterfazReserva ar = (InterfazReserva)Naming.lookup("//" + this.ip + "/AccesoReserva");
			ar.deleteMesas(id_reserva);
		} catch (MalformedURLException e) {
			System.err.println("Error en la clase Reserva en el metodo setMesaTitular: " + e.getMessage());
		} catch (RemoteException e) {
			System.err.println("Error en la clase Reserva en el metodo setMesaTitular: " + e.getMessage());
		} catch (NotBoundException e) {
			System.err.println("Error en la clase Reserva en el metodo setMesaTitular: " + e.getMessage());
		}
		m_Mesas = null;
	}
	
}
